package dp.mobile.glwrapper;

import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.IOException;

import javax.microedition.khronos.opengles.GL10;

import dp.mobile.system.Utilities;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Bitmap.Config;
import android.opengl.GLUtils;
import android.provider.UserDictionary.Words;
import android.util.Log;

public class GLFontLibrary {
	private static final String TAG = "Font Library";
	
	private GLFontLibrary() {
		
	}
	
	public static GLFontLibrary createFont(GL10 gl, String fontPath) throws IOException {
		GLFontLibrary font 	= new GLFontLibrary();
		DataInputStream dis = new DataInputStream(new BufferedInputStream(new FileInputStream(fontPath)));
		
		int len = dis.readInt();
		font.mCharacters 	= new char[len];
		font.mTexture		= new GLTiledTexture[len];
		font.mCharsWidth	= new byte[len];
		
		for (int i = 0; i < len; ++i) {
			font.mCharacters[i] = dis.readChar();
			font.mCharsWidth[i] = dis.readByte();
		}
		int imageSize = dis.readInt();
		byte[] buffer = new byte[imageSize];
		dis.read(buffer, 0, imageSize);
		
		
		Bitmap tempBmp = BitmapFactory.decodeByteArray(buffer, 0, imageSize);
		Bitmap bmp = tempBmp.copy(Config.ARGB_8888, true);

		for (int x = 0; x < bmp.getWidth(); ++x){
			for (int y = 0; y < bmp.getHeight(); ++y){
				int pixel = bmp.getPixel(x, y);
				if (pixel == 0xff000000)
					pixel = 0;
				
				bmp.setPixel(x, y, pixel);
			}
		}
		
		tempBmp.recycle();
	
		// generate gl texture
		int[] workspace = new int[1];
		gl.glGenTextures(1, workspace, 0);
		font.mTexturePointer = workspace[0];
		gl.glBindTexture(GL10.GL_TEXTURE_2D, font.mTexturePointer);
		
        gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
        gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);

        gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_CLAMP_TO_EDGE);
        gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_CLAMP_TO_EDGE);
		
        gl.glTexEnvf(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE, GL10.GL_MODULATE);

        GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bmp, 0);
        
        font.mMainTexture = new GLTexture();
        font.mMainTexture.Name		= font.mTexturePointer;
        font.mMainTexture.Resource 	= fontPath;
        font.mMainTexture.Height 	= bmp.getHeight();
        font.mMainTexture.Width		= bmp.getWidth();
        font.mMainTexture.Loaded	= true;
        
        bmp.recycle();
        
        // tile texture
        float x = 0;
        final float width = font.mMainTexture.Width;
        
        for (int i = 0; i < len; ++i) {
        	final float left 	= (x + 1) / width;
        	final float right 	= (x - 1 + font.mCharsWidth[i]) / width;
        	final float[] crop = new float[] {
        		left, 1,
        		right, 1,
        		left, 0,
        		right, 0
        	};
        	font.mTexture[i] = new GLTiledTexture(font.mMainTexture, crop);
        	
        	x = x + font.mCharsWidth[i];
        }
        Log.d(TAG, "Font " + fontPath + " loaded");
        
		return font;
	}
	
	void drawText(GL10 gl, String text, float x, float y, float scale, int tint) {
		mMainTexture.Tint = tint;
		final int height = (int)(mMainTexture.Height * scale);
		for (int i = 0; i < text.length(); ++i) {
			final int index = charIndex(text.charAt(i));
			if (index == -1) continue;
			final int width = (int)(mCharsWidth[index] * scale);
			GameRenderer.instance().draw(gl, mMainTexture, mTexture[index].Crop, (int)x, (int)y, width, height, Utilities.TEXT_DEPTH);
			x += width;
		}
		mMainTexture.Tint = 0xffffffff;
	}
	
	private int charIndex(char c) {
		for (int i = 0; i < mCharacters.length; ++i) {
			if (c == mCharacters[i])
				return i;
		}
		
		return -1;
	}
	
	private int mTexturePointer;
	private GLTexture mMainTexture;
	private byte[] mCharsWidth;
	private GLTiledTexture[] mTexture;
	private char[] mCharacters;
}
